/*
 * ToDo:
 * Fix timer precision
 * Find out how to pass the recorded grunt back to the activity that called this one
 */

package com.snowflakes.gruntr;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;

public class RecordGrunt extends Activity {

	private MediaRecorder gruntBox;
	private String outputFile = null;
	private Button record, preview, stop, submit;
	private CheckBox cdTog;

	Handler handler1 = new Handler() {
		public void handleMessage(Message msg) {
			record.setText("3");
		}
	};

	Handler handler2 = new Handler() {
		public void handleMessage(Message msg) {
			record.setText("2");
		}
	};

	Handler handler3 = new Handler() {
		public void handleMessage(Message msg) {
			record.setText("1");
		}
	};

	Handler handler4 = new Handler() {
		public void handleMessage(Message msg) {
			record.setText("Recording...");
		}
	};

	Handler handler5 = new Handler() {
		public void handleMessage(Message msg) {
			record.setText("Record a grunt");
			record.setEnabled(true);
			preview.setEnabled(true);
			submit.setEnabled(true);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.record_grunt);
		record = (Button) findViewById(R.id.bRecord);
		preview = (Button) findViewById(R.id.bPreview);
		submit = (Button) findViewById(R.id.bSubmit);
		cdTog = (CheckBox) findViewById(R.id.cbCountdownToggle);

		preview.setEnabled(false);
		submit.setEnabled(false);

		new File(Environment.getExternalStorageDirectory().getAbsolutePath()
				+ "/Android/data/com.snowflakes.gruntr").mkdirs();
		outputFile = Environment.getExternalStorageDirectory()
				.getAbsolutePath()
				+ "/Android/data/com.snowflakes.gruntr/grunt.3gp";

		gruntBox = new MediaRecorder();
		gruntBox.setAudioSource(MediaRecorder.AudioSource.MIC);
		gruntBox.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
		gruntBox.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
		gruntBox.setOutputFile(outputFile);
		
		submit.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				
				ParseUser user = ParseUser.getCurrentUser();
				
				Intent i = getIntent();
				Bundle extras = i.getExtras();
				
				String id = extras.getString("id");				
				
				ParseObject grunt = new ParseObject("Grunt");
				
				String inputFile = Environment.getExternalStorageDirectory()
						.getAbsolutePath()
						+ "/Android/data/com.snowflakes.gruntr/grunt.3gp";
				
				FileInputStream fileInputStream = null;
				
				File file = new File(inputFile);
				
				byte[] bFile = new byte[(int) file.length()];
				
				 try {
			            //convert file into array of bytes
				    fileInputStream = new FileInputStream(file);
				    fileInputStream.read(bFile);
				    fileInputStream.close();
			 
				    for (int x = 0; x < bFile.length; x++) {
				       	System.out.print((char)bFile[x]);
			            }
			        }catch(Exception e){
			        	e.printStackTrace();
			        }

				
				ParseFile soundFile = new ParseFile("grunt.3gp", bFile);
				soundFile.saveInBackground();
				
				grunt.put("Sound", soundFile);
				grunt.put("CreatedBy", user);
				grunt.put("ParentPost", id);
				grunt.put("Name", user.get("name"));

				grunt.saveInBackground();
				
				ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Post");

				query.whereEqualTo("objectId", id);

				ParseObject post = null;

				try {
					post = query.getFirst();
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} finally {
					if (post != null) {
						post.increment("Grunts");
						post.saveInBackground();
					}
				}

				Toast.makeText(getBaseContext(), "Grunt Successful", Toast.LENGTH_LONG)
						.show();
				
				finish();
			}
		});

		record.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				Thread timer = new Thread() {
					public void run() {
						long nextCheckpoint;
						if (cdTog.isChecked()) {
							handler1.sendEmptyMessage(0);
							nextCheckpoint = System.currentTimeMillis() + 500;
							while (System.currentTimeMillis() < nextCheckpoint) {
								synchronized (this) {
									try {
										wait(nextCheckpoint
												- System.currentTimeMillis());
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
							handler2.sendEmptyMessage(0);
							nextCheckpoint = System.currentTimeMillis() + 500;
							while (System.currentTimeMillis() < nextCheckpoint) {
								synchronized (this) {
									try {
										wait(nextCheckpoint
												- System.currentTimeMillis());
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
							handler3.sendEmptyMessage(0);
							nextCheckpoint = System.currentTimeMillis() + 500;
							while (System.currentTimeMillis() < nextCheckpoint) {
								synchronized (this) {
									try {
										wait(nextCheckpoint
												- System.currentTimeMillis());
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
						}
						try {
							gruntBox.prepare();
							gruntBox.start();
						} catch (IllegalStateException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}
						handler4.sendEmptyMessage(0);
						nextCheckpoint = System.currentTimeMillis() + 1500;
						while (System.currentTimeMillis() < nextCheckpoint) {
							synchronized (this) {
								try {
									wait(nextCheckpoint
											- System.currentTimeMillis());
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
						handler5.sendEmptyMessage(0);
						gruntBox.stop();
						gruntBox.release();
						gruntBox = new MediaRecorder();
						gruntBox.setAudioSource(MediaRecorder.AudioSource.MIC);
						gruntBox.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
						gruntBox.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
						gruntBox.setOutputFile(outputFile);
					}
				};
				record.setEnabled(false);
				timer.start();
			}
		});

		preview.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				MediaPlayer m = new MediaPlayer();
				try {
					m.setDataSource(outputFile);
					m.prepare();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				m.start();
			}
		});
	}
}